package com.bookworld.model;

import jakarta.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

public class Order {
    private Long id;
    
    @NotNull(message = "{order.user.notnull}")
    private Long userId;
    
    @NotBlank(message = "{order.orderNumber.notblank}")
    private String orderNumber;
    
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime orderDate;
    
    @NotNull(message = "{order.totalAmount.notnull}")
    @DecimalMin(value = "0.01", message = "{order.totalAmount.min}")
    @NumberFormat(pattern = "#,##0.00")
    private BigDecimal totalAmount;
    
    @DecimalMin(value = "0.00", message = "{order.discount.min}")
    private BigDecimal discount;
    
    @DecimalMin(value = "0.00", message = "{order.tax.min}")
    private BigDecimal tax;
    
    @DecimalMin(value = "0.00", message = "{order.shippingFee.min}")
    private BigDecimal shippingFee;
    
    @DecimalMin(value = "0.01", message = "{order.finalAmount.min}")
    private BigDecimal finalAmount;
    
    @NotBlank(message = "{order.status.notblank}")
    private String status;
    
    @NotBlank(message = "{order.paymentMethod.notblank}")
    private String paymentMethod;
    
    private String paymentStatus;
    private String paymentTransactionId;
    
    // 收货信息
    @NotBlank(message = "{order.shippingName.notblank}")
    private String shippingName;
    
    @NotBlank(message = "{order.shippingAddress.notblank}")
    private String shippingAddress;
    
    @NotBlank(message = "{order.shippingCity.notblank}")
    private String shippingCity;
    
    @NotBlank(message = "{order.shippingCountry.notblank}")
    private String shippingCountry;
    
    @NotBlank(message = "{order.shippingPostalCode.notblank}")
    private String shippingPostalCode;
    
    @Pattern(regexp = "^[0-9\\-\\+\\s\\(\\)]{7,20}$", message = "{order.shippingPhone.invalid}")
    private String shippingPhone;
    
    private String shippingEmail;
    private String shippingNotes;
    
    // 物流信息
    private String trackingNumber;
    private String courier;
    private LocalDateTime shippedDate;
    private LocalDateTime deliveredDate;
    
    // 订单备注
    private String notes;
    
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
    
    // 关联对象
    private User user;
    private List<OrderItem> orderItems;

    // 订单状态常量
    public static final String STATUS_PENDING = "PENDING";
    public static final String STATUS_CONFIRMED = "CONFIRMED";
    public static final String STATUS_PROCESSING = "PROCESSING";
    public static final String STATUS_SHIPPED = "SHIPPED";
    public static final String STATUS_DELIVERED = "DELIVERED";
    public static final String STATUS_CANCELLED = "CANCELLED";
    public static final String STATUS_REFUNDED = "REFUNDED";

    // 支付方式常量
    public static final String PAYMENT_CREDIT_CARD = "CREDIT_CARD";
    public static final String PAYMENT_PAYPAL = "PAYPAL";
    public static final String PAYMENT_BANK_TRANSFER = "BANK_TRANSFER";
    public static final String PAYMENT_CASH_ON_DELIVERY = "CASH_ON_DELIVERY";

    public Order() {
        this.orderDate = LocalDateTime.now();
        this.discount = BigDecimal.ZERO;
        this.tax = BigDecimal.ZERO;
        this.shippingFee = BigDecimal.ZERO;
        this.status = STATUS_PENDING;
        this.paymentStatus = "PENDING";
        this.createdAt = LocalDateTime.now();
    }

    // 计算总金额
    public void calculateTotal() {
        BigDecimal itemsTotal = orderItems.stream()
                .map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        this.totalAmount = itemsTotal;
        this.finalAmount = totalAmount.add(tax).add(shippingFee).subtract(discount);
    }

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getOrderNumber() {
        return orderNumber;
    }

    public void setOrderNumber(String orderNumber) {
        this.orderNumber = orderNumber;
    }

    public LocalDateTime getOrderDate() {
        return orderDate;
    }

    public void setOrderDate(LocalDateTime orderDate) {
        this.orderDate = orderDate;
    }

    public BigDecimal getTotalAmount() {
        return totalAmount;
    }

    public void setTotalAmount(BigDecimal totalAmount) {
        this.totalAmount = totalAmount;
    }

    public BigDecimal getDiscount() {
        return discount;
    }

    public void setDiscount(BigDecimal discount) {
        this.discount = discount;
    }

    public BigDecimal getTax() {
        return tax;
    }

    public void setTax(BigDecimal tax) {
        this.tax = tax;
    }

    public BigDecimal getShippingFee() {
        return shippingFee;
    }

    public void setShippingFee(BigDecimal shippingFee) {
        this.shippingFee = shippingFee;
    }

    public BigDecimal getFinalAmount() {
        return finalAmount;
    }

    public void setFinalAmount(BigDecimal finalAmount) {
        this.finalAmount = finalAmount;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getPaymentMethod() {
        return paymentMethod;
    }

    public void setPaymentMethod(String paymentMethod) {
        this.paymentMethod = paymentMethod;
    }

    public String getPaymentStatus() {
        return paymentStatus;
    }

    public void setPaymentStatus(String paymentStatus) {
        this.paymentStatus = paymentStatus;
    }

    public String getPaymentTransactionId() {
        return paymentTransactionId;
    }

    public void setPaymentTransactionId(String paymentTransactionId) {
        this.paymentTransactionId = paymentTransactionId;
    }

    public String getShippingName() {
        return shippingName;
    }

    public void setShippingName(String shippingName) {
        this.shippingName = shippingName;
    }

    public String getShippingAddress() {
        return shippingAddress;
    }

    public void setShippingAddress(String shippingAddress) {
        this.shippingAddress = shippingAddress;
    }

    public String getShippingCity() {
        return shippingCity;
    }

    public void setShippingCity(String shippingCity) {
        this.shippingCity = shippingCity;
    }

    public String getShippingCountry() {
        return shippingCountry;
    }

    public void setShippingCountry(String shippingCountry) {
        this.shippingCountry = shippingCountry;
    }

    public String getShippingPostalCode() {
        return shippingPostalCode;
    }

    public void setShippingPostalCode(String shippingPostalCode) {
        this.shippingPostalCode = shippingPostalCode;
    }

    public String getShippingPhone() {
        return shippingPhone;
    }

    public void setShippingPhone(String shippingPhone) {
        this.shippingPhone = shippingPhone;
    }

    public String getShippingEmail() {
        return shippingEmail;
    }

    public void setShippingEmail(String shippingEmail) {
        this.shippingEmail = shippingEmail;
    }

    public String getShippingNotes() {
        return shippingNotes;
    }

    public void setShippingNotes(String shippingNotes) {
        this.shippingNotes = shippingNotes;
    }

    public String getTrackingNumber() {
        return trackingNumber;
    }

    public void setTrackingNumber(String trackingNumber) {
        this.trackingNumber = trackingNumber;
    }

    public String getCourier() {
        return courier;
    }

    public void setCourier(String courier) {
        this.courier = courier;
    }

    public LocalDateTime getShippedDate() {
        return shippedDate;
    }

    public void setShippedDate(LocalDateTime shippedDate) {
        this.shippedDate = shippedDate;
    }

    public LocalDateTime getDeliveredDate() {
        return deliveredDate;
    }

    public void setDeliveredDate(LocalDateTime deliveredDate) {
        this.deliveredDate = deliveredDate;
    }

    public String getNotes() {
        return notes;
    }

    public void setNotes(String notes) {
        this.notes = notes;
    }

    public LocalDateTime getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(LocalDateTime createdAt) {
        this.createdAt = createdAt;
    }

    public LocalDateTime getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(LocalDateTime updatedAt) {
        this.updatedAt = updatedAt;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public List<OrderItem> getOrderItems() {
        return orderItems;
    }

    public void setOrderItems(List<OrderItem> orderItems) {
        this.orderItems = orderItems;
    }

    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", orderNumber='" + orderNumber + '\'' +
                ", status='" + status + '\'' +
                ", finalAmount=" + finalAmount +
                '}';
    }
}
